24. Type_Cast for Non-member Function

암시적 변환 제공 클래스
class Rational{
public:
// explicit
Rational(int numerator=0, int denominator=1);
int numerator(void) const;
int denominator(void) const; //
const operator*(const Rational& rhs) const; // operator*
private:
int numerator, denominator;
// ...
};
위에서 operator*를 멤버함수로 정의하였다.
위 같이 멤버로 선언한 operator*에 대하여 Rational과 int 연산은 교환법칙이 성립되지 않는다.
Rational oneEight(1, 8);
Rational oneHalf(1, 2);
Rational result=oneHalf*oneEight
result=result*oneHalf; //
result=oneHalf*2; //
result=2*oneHalf; // error
result=oneHalf 와 result=2*oneHalf 연산은 내부적으로 아래와 같다.
result=oneHalf.operator*(2);
result=2.operator*(oneHalf);
정수 int.operator* 멤버 함수는 존재하지 않는다.
Rational을 explicit으로 선언하지 않았기 때문에 Rational(2)는 객체를 생성한다.

호출되는 멤버함수를 갖고 있는 객체(this)에 대해서는 암시적 변환을 허용하지 않는다.
혼합형 수치 연산을 지원하고 싶은 경우, operator*를 비멤버 함수로 선언해 주어야 한다.
class Rational{
// ... without operator*
};
const Rational operator*(const Rational& lhs, const Rational& rhs){
return Rational(lhs.numerator()*rhs.numerator(), lhs.denominator()*rhs.denominator());
}
Rational oneFourth(1, 4);
Rational result;
result=oneFourth*4; //
result=2*oneFourth; //
어떤 함수(연산자 포함)에 대하여 매개변수 타입 변환이 필요하다면(특히 this 포인터가 가르키는 객체),
해당 함수는 비멤버 함수이어야 한다.